package muti;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 通用的线程优雅停止办法实例
 */

public class TerminatableTaskRunner implements TaskRunnerSpec {
    protected final BlockingQueue<Runnable> channel;
    //停止线程标记
    protected volatile boolean inUse = true;
    //待处理任务计数器
    public final AtomicInteger reservations = new AtomicInteger(0);

    private volatile Thread workerThread;

    public TerminatableTaskRunner(BlockingQueue<Runnable> channel) {
        this.channel = channel;
        this.workerThread = new WorkerThread();
    }

    public TerminatableTaskRunner() {
        this(new LinkedBlockingQueue<Runnable>());
    }

    @Override
    public void init() {
        final Thread t = workerThread;
        if(null != t){
            t.start();
        }
    }

    @Override
    public void submit(Runnable task) throws InterruptedException {
        channel.put(task);
        reservations.incrementAndGet();//语句1
    }


    public void shutdown(){
        System.out.println("Shuting down service...");
        inUse = false;//语句2
        final Thread t = workerThread;
        if(t != null){
            t.interrupt();//语句3
        }
    }

    class WorkerThread extends Thread {

        @Override
        public void run(){
            Runnable task = null;
            try {
                for(;;){
                    //线程不再被需要，且无待处理任务
                    if(!inUse && reservations.get() <= 0){
                        break;
                    }
                    task = channel.take();
                    try{
                        task.run();
                    }catch (Throwable e){
                        e.printStackTrace();
                    }
                    //使待处理的任务数减少1
                    reservations.decrementAndGet();//语句5
                }
            }catch (InterruptedException e){
                workerThread = null;
            }
            System.out.println("worker thread terminated.");
        }
    }

}
